package com.kandinfo.base.security.controller;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.credential.PasswordService;
import org.apache.shiro.util.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.kandinfo.base.admin.domain.DictData;
import com.kandinfo.base.admin.domain.UserGroup;
import com.kandinfo.base.admin.domain.WorkGroup;
import com.kandinfo.base.admin.dto.WorkGroupPostDto;
import com.kandinfo.base.admin.enumeration.DictType;
import com.kandinfo.base.admin.service.DictDataService;
import com.kandinfo.base.admin.service.UserGroupService;
import com.kandinfo.base.admin.service.WorkGroupService;
import com.kandinfo.base.common.converter.ConverterService;
import com.kandinfo.base.common.dto.ResultDto;
import com.kandinfo.base.common.dto.ResultDtoFactory;
import com.kandinfo.base.common.dto.annotation.OnValid;
import com.kandinfo.base.common.dto.widget.DataTablesResponseDto;
import com.kandinfo.base.common.util.Constants;
import com.kandinfo.base.security.SecurityContext;
import com.kandinfo.base.security.annotation.Menu;
import com.kandinfo.base.security.domain.Role;
import com.kandinfo.base.security.domain.User;
import com.kandinfo.base.security.domain.UserRole;
import com.kandinfo.base.security.dto.UserDto;
import com.kandinfo.base.security.dto.UserSearchDto;
import com.kandinfo.base.security.service.RoleService;
import com.kandinfo.base.security.service.UserRoleService;
import com.kandinfo.base.security.service.UserService;
/**
 * 
 * Class Name: UserController Description: TODO
 * 
 * @author
 *
 */
@Controller
public class UserController {
    @SuppressWarnings("unused")
    private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private RoleService roleService;

    @Autowired
    private PasswordService passwordService;

    @Autowired
    private UserService userService;

    @Autowired
    private SecurityContext securityContext;
    @Autowired
    private UserGroupService userGroupService;
    @Autowired
    private WorkGroupService workGroupService;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private DictDataService dictDataService;

    /**
     * Description: 修改个人信息
     *
     * @param id
     * @param adminUserDto
     * @return
     */
    @RequestMapping(value = "/adminuser/doChangePassword", method = RequestMethod.POST)
    @ResponseBody
    public ResultDto doChangePassword(@RequestBody UserDto userDto, BindingResult result) {
        Long id = userDto.getId();
        if (id == null) {
            return ResultDtoFactory.toNack("修改失败");
        } else {
            User user = userService.findUserById(id);
            String oldpwd = passwordService.encryptPassword(getPassword(userDto.getOldPassword(), user.getUsername()));

            if (!oldpwd.equalsIgnoreCase(user.getPassword())) {
                return ResultDtoFactory.toNack("当前密码输入不正确!");
            } else {
                String encrytPasswrod = passwordService.encryptPassword(getPassword(userDto.getNewPassword(), user.getUsername()));
                user.setPassword(encrytPasswrod);
                user.setMobile(userDto.getMobile());
                userService.saveUser(user);
                return ResultDtoFactory.toAck("修改成功!");
            }
        }

    }

    /**
     * Description: 显示个人信息
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/adminuser/toChangePassword/{id}", method = RequestMethod.GET)
    @ResponseBody
    public UserDto toChangePassword(@PathVariable("id") Long id) {
        User adminUser = userService.findUserById(id);
        return ConverterService.convert(adminUser, UserDto.class);
    }

    @RequestMapping(value = "/adminuser", method = RequestMethod.GET)
    @Menu
    public String home(Model model) {
        Map<String, List<DictData>> map = dictDataService.getDict(DictType.USER_STATUS, DictType.USER_WORK_STATUS,DictType.USER_NATRUE);
        model.addAttribute("dict", map);
        model.addAttribute("groupList", workGroupService.findAll());
        model.addAttribute("roleList", roleService.findRoleNotAdmin());

        return "sys/user_list";
    }

    @RequestMapping(value = "/adminuser/searchbyCon", method = RequestMethod.POST)
    @ResponseBody
    public DataTablesResponseDto<UserDto> searchByCon(@RequestBody UserSearchDto request) {
        DataTablesResponseDto<UserDto> resp = userService.searchByCon(request);
        resp.setEcho(request.getEcho());
        return resp;
    }

    @RequestMapping(value = "/adminuser/getgroupList", method = RequestMethod.GET)
    @ResponseBody
    public ResultDto findgroupList(@RequestParam Long userId) {
        List<WorkGroup> groupList = workGroupService.findWorkGroupByUserId(userId);
        return ResultDtoFactory.toAckNomessage(groupList);
    }

    @RequestMapping(value = "/adminuser/toAdd", method = RequestMethod.GET)
    @ResponseBody
    public List<Role> toAdd() {
        return roleService.findAll();
    }

    @RequestMapping(value = "/adminuser/toEdit/{id}", method = RequestMethod.GET)
    @ResponseBody
    public UserDto toEdit(@PathVariable(value = "id") Long id, Model model) {
        User adminUser = userService.findUserById(id);
        UserDto adminUserDto = ConverterService.convert(adminUser, UserDto.class);
        List<UserRole> roleList = userRoleService.findByUserId(id);
        adminUserDto.setRoleList(roleList);
        return adminUserDto;
    }

    @RequestMapping(value = "/adminuser/toResetPassword/{id}", method = RequestMethod.GET)
    @ResponseBody
    public UserDto toResetPassword(@PathVariable("id") Long id, Model model) {
        User adminUser = userService.findUserById(id);
        return ConverterService.convert(adminUser, UserDto.class);
    }

    @RequestMapping(value = "/adminuser/doResetPassword/{id}", method = RequestMethod.POST)
    @ResponseBody
    public ResultDto doResetPassword(@RequestBody UserDto userDto, @PathVariable("id") Long id, BindingResult result) {
        String message = "";
        User user = userService.findUserById(id);
        if (Constants.USER_DELETE.equals(user.getStatus())) {
            message = "用户已经停用!";
        } else {
            String encrytPasswrod = passwordService.encryptPassword(getPassword(userDto.getNewPassword(), userDto.getUsername()));
            user.setPassword(encrytPasswrod);
            userService.saveUser(user);
            message = "密码设置成功!";
        }
        return ResultDtoFactory.toAck(message);
    }

    private String getPassword(String pass, String username) {
        return pass + Integer.toString(username.substring(0, 4).hashCode());
    }

    @RequestMapping(value = "/adminuser/doAdd", method = RequestMethod.POST)
    @ResponseBody
    public ResultDto doAdd(@OnValid @RequestBody UserDto adminUserDto, BindingResult result, Model model) {

        String username = adminUserDto.getUsername().trim();
        adminUserDto.setUsername(username);

        User loginUser = securityContext.getCurrentUser();
        User checkUser = userService.findUserByUsername(adminUserDto.getUsername());
        if (checkUser != null) {
            return ResultDtoFactory.toNack("此用户名已经存在!");
        } else {
            String[] roles = adminUserDto.getRoleIds().split(",");
            User user = ConverterService.convert(adminUserDto, User.class);
            String pwd = passwordService.encryptPassword(getPassword(Constants.DEFAULT_PASSWORD, user.getUsername()));
            user.setPassword(pwd);
            user.setStatus(Constants.USER_ACTIVE);
            User newUser = userService.saveUser(user);
            Long userId = newUser.getId();
            int rolesLength = roles == null ? 0 : roles.length;
            if (rolesLength > 0) {
                for (int i = 0; i < roles.length; i++) {
                	if(StringUtils.isEmpty(roles[i])) {
                		continue;
                	}
                    UserRole userRole = new UserRole();
                    userRole.setUserId(userId);
                    userRole.setRoleId(Long.valueOf(roles[i].trim()));
                    userRole.setCreateTs(new Date());
                    userRole.setCreateBy(loginUser.getId());
                    userRoleService.save(userRole);
                }
            }

            return ResultDtoFactory.toAck("新建成功");
        }
    }

    @RequestMapping(value = "/adminuser/doDelete/{id}", method = RequestMethod.DELETE)
    @ResponseBody
    public ResultDto doDelete(@PathVariable("id") Long id) {
        userService.deleteUser(id);
        return ResultDtoFactory.toAck("禁用成功!");
    }

    @RequestMapping(value = "/adminuser/doReuse/{id}", method = RequestMethod.POST)
    @ResponseBody
    public ResultDto doReuse(@PathVariable("id") Long id) {
        userService.reuseUser(id);
        return ResultDtoFactory.toAck("复用成功");
    }

    @RequestMapping(value = "/adminuser/doEdit/{id}", method = RequestMethod.POST)
    @ResponseBody
    public ResultDto doEdit(@PathVariable(value = "id") Long id, @RequestBody UserDto adminUserDto) throws Exception {
        String userName = adminUserDto.getUsername().trim();
        adminUserDto.setUsername(userName);
        adminUserDto.setName(adminUserDto.getName().trim());
        // 判断用户名是否重复
        String message = "";
        User loginUser = securityContext.getCurrentUser();
        User checkUser = userService.findUserByUsername(adminUserDto.getUsername());

        if (Constants.USER_DELETE.equals(checkUser.getStatus())) {
            message = "此用户已经禁用！";
        } else {
            String[] roles = adminUserDto.getRoleIds().split(",");
            User user = userService.findUserById(id);
            List<UserRole> list = userRoleService.findByUserId(user.getId());
            if (!CollectionUtils.isEmpty(list)) {
                userRoleService.delete(list);
            }
            user.setUsername(adminUserDto.getUsername());
            user.setName(adminUserDto.getName());
//            user.setUserType(adminUserDto.getUserType());
            user.setEmail(adminUserDto.getEmail());
            user.setMobile(adminUserDto.getMobile());
            userService.saveUser(user);
            int rolesLength = roles == null ? 0 : roles.length;
            if (rolesLength > 0) {
                for (int i = 0; i < roles.length; i++) {
                    UserRole userRole = new UserRole();
                    userRole.setUserId(id);
                    userRole.setRoleId(Long.valueOf(roles[i].trim()));
                    userRole.setCreateTs(new Date());
                    userRole.setCreateBy(loginUser.getId());
                    userRoleService.save(userRole);
                }
            }
            message = "修改成功";
        }
        return ResultDtoFactory.toAck(message);
    }

    // 提交用户组数据
    @RequestMapping(value = "/adminuser/assignGroup", method = RequestMethod.POST)
    @ResponseBody
    public ResultDto assignUsers(@RequestBody WorkGroupPostDto workGroupPostDto) {
        Long userId = Long.parseLong(workGroupPostDto.getUserId().trim());
        String[] groupIds = workGroupPostDto.getRefId().split(",");
        int groupIdsLength = "".equals(groupIds[0]) ? 0 : groupIds.length;
        User loginUser = SecurityContext.getInstance().getCurrentUser();
        List<UserGroup> originalGroups = userGroupService.findByUserId(userId);
        if (!CollectionUtils.isEmpty(originalGroups)) {
            userGroupService.delete(originalGroups);
        }
        int count = groupIdsLength;
        if (groupIdsLength > 0) {
            for (int i = 0; i < groupIdsLength; i++) {
                UserGroup temp = new UserGroup();
                temp.setGroupId(Long.valueOf(groupIds[i].trim()));
                temp.setUserId(userId);
                temp.setCreateTs(new Date());
                temp.setCreateBy(loginUser.getId());

                UserGroup saved = userGroupService.save(temp);
                if (saved != null) {
                    count--;
                }
            }
        }
        if (count == 0) {
            return ResultDtoFactory.toAck("保存成功");
        } else {
            // 回滚数据
            List<UserGroup> nowgroupPerms = userGroupService.findByUserId(userId);
            if (nowgroupPerms != null && nowgroupPerms.size() > 0) {
                userGroupService.delete(nowgroupPerms);
            }

            for (UserGroup item : originalGroups) {
                UserGroup temp = new UserGroup();
                temp.setId(item.getGroupId());
                temp.setUserId(item.getUserId());
                temp.setCreateTs(item.getCreateTs());
                temp.setCreateBy(item.getCreateBy());
                userGroupService.save(temp);
            }
            return ResultDtoFactory.toNack("保存失败");
        }
    }

    @RequestMapping(value = "/adminuser/changeWorkStatus/{id}", method = RequestMethod.GET)
    @ResponseBody
    public ResultDto changeWorkStatus(@PathVariable(value = "id") Long id) {
//        User loginUser = securityContext.getCurrentUser();
//        User user = userService.findUserById(id);
        String msg = "";
//        if (UserWorkStatusConstant.IN_WORKSTATUS.equals(user.getWorkStatus())) {
//            user.setWorkStatus(UserWorkStatusConstant.NOT_IN_WORKSTATUS);
//            msg = "已暂停工作,请重新登录";
//            LOGGER.info("~~~~~~~~~\n"+new Date()+" \n"+user.getName()+"暂停了工作。操作人："+loginUser.getName());
//        } else {
//            user.setWorkStatus(UserWorkStatusConstant.IN_WORKSTATUS);
//            msg = "已开启工作，请重新登录";
//        }
//        userService.updateWorkStatusUser(user);
        return ResultDtoFactory.toAck(msg);
    }
}
